package com.fengniao.file.util;

import com.fengniao.file.def.FastDFSFile;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.core.io.ClassPathResource;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author lanhai
 * @date 2021/7/4 22:54
 * 实现FastDFS文件管理
 *      文件上传、下载、信息获取
 *      Storage信息获取 Tracker信息获取
 */
public class FastDFSUtil {

    private FastDFSUtil() {}

    /**
     * 加载Tracker链接信息
     */
    static {
        try {
            // 查找classpath下的路径
            String filename = new ClassPathResource("fdfs_client.conf").getPath();
            // 加载Tracker链接信息
            ClientGlobal.init(filename);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取StorageClient
     * @return
     * @throws IOException
     */
    public static StorageClient getStorageClient() throws IOException {
        // 1.获取trackerClient
        TrackerClient trackerClient = new TrackerClient();
        // 2.获取trackerServer
        TrackerServer trackerServer = trackerClient.getConnection();
        // 3.创建storageClient并返回
        return new StorageClient(trackerServer, null);
    }

    /**
     * 文件上传
     * @param fastDFSFile 封装上传的文件信息
     */
    public static String[] upload(FastDFSFile fastDFSFile) throws Exception {

        // 附加参数
        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author", fastDFSFile.getAuthor());

        StorageClient storageClient = getStorageClient();

        // 通过StorageClient访问Storage,实现文件上传,
        //   并且获取文件存储信息
        // uploads[0]:storage组名 uploads[1]:存储到storage中的文件名
        String[] uploads = storageClient.upload_file(fastDFSFile.getContent(),
                fastDFSFile.getExt(), meta_list);
        return uploads;
    }

    /**
     * 获取文件信息
     * @param groupName 文件的组名
     * @param remoteFileName 文件的存储路径名
     * @return FileInfo对象,封装了ip 大小 创建时间 crc32签名信息
     */
    public static FileInfo getFileInfo(String groupName, String remoteFileName) throws Exception{
        // 1.获取storageClient
        StorageClient storageClient = getStorageClient();

        // 2.通过storageClient获取FileInfo
        return storageClient.get_file_info(groupName, remoteFileName);
    }

    /**
     * 文件下载
     * @param groupName 文件组名
     * @param remoteFileName 文件名
     * @return InputStream 输入流
     * @throws Exception
     */
    public static InputStream downloadFile(String groupName, String remoteFileName) throws Exception {
        StorageClient storageClient = getStorageClient();

        byte[] buffer = storageClient.download_file(groupName, remoteFileName);
        return new ByteArrayInputStream(buffer);
    }

    /**
     * 删除文件
     * @param groupName 文件组名
     * @param remoteFileName 文件名
     * @return true->删除成功 false->失败
     * @throws Exception
     */
    public static boolean deleteFile(String groupName, String remoteFileName) throws Exception {
        StorageClient storageClient = getStorageClient();

        int i = storageClient.delete_file(groupName, remoteFileName);
        // 0=成功删除 2=找不到文件
        return i == 0;
    }

    /**
     * 获取Storage组信息
     * @param groupName 文件组名
     * @return
     */
    public static StorageServer getStorage(String groupName) {
        try {
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            // 通过trackerClient获取Storage组信息
            return trackerClient.getStoreStorage(trackerServer, groupName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取Storage组的IP和端口信息
     * @param groupName
     * @param remoteFileName
     * @return
     * @throws Exception
     */
    public static ServerInfo[] getServerInfos(String groupName, String remoteFileName) throws Exception {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();

        // 获取Storage的IP和端口信息
        return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
    }

    /**
     * 获取tracker的ip和端口
     * @return
     */
    public static String getTrackerInfo() throws Exception{
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();

        String ip = trackerServer.getInetSocketAddress().getHostString();
        int port = ClientGlobal.getG_tracker_http_port();
        return "http://" + ip + ":" + port;
    }
}
